package com.emm.yixun.website.controller.process;
import java.util.ArrayList;
import java.util.List;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.history.ProcessInstanceHistoryLog;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.emm.yixun.common.enums.ProcessTypeEnums;
import com.emm.yixun.common.enums.ResponseEnums;
import com.emm.yixun.common.model.User;
import com.emm.yixun.common.model.dto.UserDto;
import com.emm.yixun.common.model.enums.SsoLoginEnum;
import com.emm.yixun.common.response.Response;
import com.emm.yixun.common.response.ResponseList;
import com.emm.yixun.system.service.BusinessLogServiceFacade;
import com.emm.yixun.system.service.NodeUserServiceFacade;
import com.emm.yixun.system.service.UserServiceFacade;
import com.emm.yixun.website.common.ajax.AjaxRes;
import com.emm.yixun.website.common.utils.base.Const;
import com.emm.yixun.website.common.utils.security.ShiroUtil;
import com.emm.yixun.website.constant.PmoConfig;
import com.emm.yixun.website.service.ActivitiProcessServiceImpl;
import com.emm.yixun.website.service.ao.DataService.OaDataService;
import com.emm.yixun.website.utils.Arithmetic;
import com.emm.yixun.website.vo.process.EnumsVo;
import com.emm.yixun.website.vo.process.HistoryTaskInfoVo;
import com.emm.yixun.website.vo.process.ProcdefVo;
import com.emm.yixun.website.vo.process.ProcessScheduleVo;

@Controller
@RequestMapping("/processComponent/")
public class ProcessComponentController {
	protected Logger logger = LoggerFactory.getLogger(this.getClass());
	@Autowired
	private TaskService taskService;
	@Autowired
	private HistoryService historyService;
	@Autowired
	private ActivitiProcessServiceImpl activitiProcessServiceImpl;
	@Autowired
	private UserServiceFacade userServiceFacade;
	@Autowired
	private RepositoryService repositoryService;
	@Autowired
	private OaDataService oaDataService;
	@Autowired
	private PmoConfig pmoConfig;
	@Autowired
	private BusinessLogServiceFacade businessLogServiceFacade;
	
	@RequestMapping(value = "index")
	public String processComponent(String jumpUrl, String id, String taskId, ModelMap map,String loginId) {
    	boolean flag = true;
    	if(!StringUtils.isEmpty(loginId)){
    	    try {
	    		Arithmetic.getKey(pmoConfig.getOaSysCode());
	    		String uid = Arithmetic.getDesString(loginId);
	    		if(!StringUtils.isEmpty(uid)){
	    		    Response<User> user =  userServiceFacade.findById(new Long(uid));
	    		    if(user.isSuccess()&&user.getEntity()!=null){
		    			Subject currentUser = SecurityUtils.getSubject();  
		    			String userName = user.getEntity().getUserAccount();
			    		userName = SsoLoginEnum.PREFIX.getNo() + userName + SsoLoginEnum.SUFFIX.getNo();
			    		UsernamePasswordToken token = new UsernamePasswordToken(userName, user.getEntity().getUserPassword(), true);
			    		// 验证是否登录成功
			    		currentUser.login(token);
	    		    }else{
		    			flag = false;
	    		    }
	    		}else{
	    		    flag = false;
	    		}
	    		
		    } catch (Exception e) {
		    	flag = false;
		    }
    	}
    	if(flag){
    	    map.put("jumpUrl", jumpUrl + "?id=" + id + "&processFlag=true");
    	    map.put("taskId", taskId);
    	    Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
    	    map.put("processInstanceId", task == null ? "0" : task.getProcessInstanceId());
    	    return "/components/processComponent";
    	}else{
    	    return "system/login/login";
    	}
		
	}

	// 审核
	@RequestMapping(value = "processPass")
	@ResponseBody
	public AjaxRes processPass(String taskId, String checkStatus, String message) {
		AjaxRes ar = new AjaxRes();
		User user = ShiroUtil.getCurrentUser();
	    try {
	    	ar = oaDataService.processCheck(taskId, checkStatus, message,user.getId());
		} catch (Exception ex) {
			if(ex.getMessage().contains(ResponseEnums.RESPONSEENUMS_999999.getName())) {
				ar.setResMsg(ResponseEnums.RESPONSEENUMS_999999.getName());
				ar.setRes(Const.OTHER);
			}else {
				ar.setFailMsg("审核失败");
			}
			logger.error("审批失败", ex);
			//新增业务操作异常记录
			businessLogServiceFacade.saveExceptionLog(user, "审批失败", taskId+"|"+checkStatus+"|"+message, JSONObject.toJSONString(ex));
		}
	    return ar;
	    
	}

	// 查询历史审批结果
	@SuppressWarnings("unused")
	@RequestMapping(value = "queryHistoricActivity")
	@ResponseBody
	public AjaxRes queryHistoricActivity(String processInstanceId, ModelMap map) {
		AjaxRes ar = new AjaxRes();
		try {
			List<HistoryTaskInfoVo> userTaskList = new ArrayList<HistoryTaskInfoVo>();
			List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()
					.processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().desc().list();
			HistoryTaskInfoVo startTaskInfoVo = null;
			HistoryTaskInfoVo endTaskInfoVo = null;
			for (HistoricActivityInstance hai : list) {
				String activityType = hai.getActivityType();
				if (activityType.equals("startEvent")) {
					ProcessInstanceHistoryLog processInstanceHistoryLog = historyService
							.createProcessInstanceHistoryLogQuery(hai.getProcessInstanceId()).singleResult();
					startTaskInfoVo = new HistoryTaskInfoVo();
					startTaskInfoVo.setTaskName("启动");
					UserDto ud = new UserDto();
					ud.setUserAccount(processInstanceHistoryLog.getStartUserId());
					ResponseList<User> userList = userServiceFacade.findByDto(ud);
					if (userList.isSuccess() && null != userList.getEntity()) {
						startTaskInfoVo.setTaskUserName(userList.getEntity().get(0).getUserName());
					}

					startTaskInfoVo.setTaskCheckStatus("发起");
					startTaskInfoVo.setStartDate(hai.getStartTime());
					startTaskInfoVo.setEndDate(hai.getEndTime());
					continue;
				}
				if (activityType.equals("endEvent")) {
					startTaskInfoVo = new HistoryTaskInfoVo();
					startTaskInfoVo.setTaskName("结束");
					startTaskInfoVo.setTaskUserName("");
					startTaskInfoVo.setTaskCheckStatus("结束");
					startTaskInfoVo.setStartDate(hai.getStartTime());
					startTaskInfoVo.setEndDate(hai.getEndTime());
					continue;
				}
				List<Comment> commentList = taskService.getTaskComments(hai.getTaskId());
				HistoryTaskInfoVo htf = new HistoryTaskInfoVo();
				htf.setTaskName(hai.getActivityName());
				htf.setStartDate(hai.getStartTime());
				htf.setEndDate(hai.getEndTime());
				if (null != commentList && commentList.size() > 0) {
					String userAccount = commentList.get(0).getUserId();
					UserDto ud = new UserDto();
					ud.setUserAccount(userAccount);
					ResponseList<User> userList = userServiceFacade.findByDto(ud);
					if (userList.isSuccess() && null != userList.getEntity()) {
						htf.setTaskUserName(userList.getEntity().get(0).getUserName());
					}

				}

				List<HistoricVariableInstance> variableList = historyService.createHistoricVariableInstanceQuery()
						.taskId(hai.getTaskId()).list();
				String taskCheckStatusName = "待审核";
				if (null != variableList && variableList.size() > 0) {
					for (HistoricVariableInstance variable : variableList) {
						if (variable.getVariableName().equals("taskCheckStatus")) {
							taskCheckStatusName = variable.getValue().equals("0") ? "审核通过" : "审核不通过";
						}

					}
				}
				htf.setTaskCheckStatus(taskCheckStatusName);
				userTaskList.add(htf);
			}
			List<HistoryTaskInfoVo> taskList = new ArrayList<HistoryTaskInfoVo>();
			if (null != endTaskInfoVo)
				taskList.add(endTaskInfoVo);
			taskList.addAll(userTaskList);
			if (null != startTaskInfoVo)
				taskList.add(startTaskInfoVo);
			ar.setSucceed(taskList);
		} catch (Exception e) {
			ar.setFailMsg("查询流程历史失败");
			e.printStackTrace();
			logger.error("查询流程历史失败", e);
		}

		return ar;
	}

	@RequestMapping(value = "processSchedule")
	public String processSchedule(String processInstanceId, ModelMap map) {
		User user = ShiroUtil.getCurrentUser();
		List<ProcessScheduleVo> list = activitiProcessServiceImpl.getProcessScheduleList(user.getMerchantId(),
				processInstanceId);
		ProcessScheduleVo startProcessScheduleVo = new ProcessScheduleVo();
		ProcessScheduleVo endProcessScheduleVo = new ProcessScheduleVo();
		List<ProcessScheduleVo> userTaskList = new ArrayList<ProcessScheduleVo>();
		for (ProcessScheduleVo psv : list) {
			if(null == psv){
				continue;
			}
			if (psv.getIsFirst()) {
				startProcessScheduleVo = psv;
			} else if (psv.getIsLast()) {
				endProcessScheduleVo = psv;
			} else {
				userTaskList.add(psv);
			}
		}
		map.put("userTaskList", userTaskList);
		map.put("startProcessScheduleVo", startProcessScheduleVo);
		map.put("endProcessScheduleVo", endProcessScheduleVo);
		return "/components/processSchedule";
	}

	// 流程类型
	@RequestMapping(value = "processTypeList", method = RequestMethod.POST)
	@ResponseBody
	public AjaxRes processTypeList() {
		AjaxRes ar = new AjaxRes();
		List<EnumsVo> list = new ArrayList<EnumsVo>();
		for (ProcessTypeEnums pte : ProcessTypeEnums.values()) {
			if("0".equals(pte.getInit())){
				EnumsVo ev = new EnumsVo();
				ev.setNo(pte.getNo());
				ev.setDes(pte.getDes());
				list.add(ev);
			}
		}
		ar.setSucceed(list);
		return ar;
	}

	// 查询已部署流程
	@RequestMapping(value = "procdefList", method = RequestMethod.POST)
	@ResponseBody
	public AjaxRes procdefList() {
		AjaxRes ar = new AjaxRes();
		ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
		List<ProcessDefinition> processDefinitionList = query.orderByDeploymentId().desc().list();
		List<ProcdefVo> pvList = new ArrayList<ProcdefVo>();
		for (ProcessDefinition pd : processDefinitionList) {
			ProcdefVo pv = new ProcdefVo();
			pv.setProcdefId(pd.getId());
			pv.setProcdefName(pd.getName());
			if (!pd.getName().equals("面积补差审批")) {
				pvList.add(pv);
			}

		}
		ar.setSucceed(pvList);
		return ar;
	}
}
